home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 9825 / 9825.xpi / chrome / content / endless_pages.js < prev    next >
Text File  |  2010-01-20  |  26KB  |  658 lines

  1. //Note to editor: NOT executed from XUL
  2. //Copyright 2009 Yongqian Li.
  3. //javascript:        var scrollHeight = document.documentElement.scrollHeight;        var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);        var clientHeight = Math.min(document.documentElement.clientHeight, document.body.clientHeight);        var remaining = scrollHeight - scrollTop - clientHeight;alert(remaining);
  4. /*
  5.  
  6. mail.google.com / a        / 10gic.net / #inbox / p3
  7. mail.google.com / support  / bin       / answer.py?hl=en&ctx=mail&answer=15049
  8.  
  9. <= 5 diff eliminate. still multiply
  10. */
  11.  
  12.  
  13. $.prototype.ready = function(callback) {
  14.     callback();
  15. };//doesn't work on Chrome, cheap hack
  16. $(document).ready(function()
  17. {
  18.     var safe_SW_getBoolPref = function(name)
  19.     {
  20.         try
  21.         {
  22.             return SW_getBoolPref(name);
  23.         }
  24.         catch(err)
  25.         {
  26.             return null;
  27.         }
  28.     };
  29.  
  30.     var getBoolPref = function(pref_name, callback)
  31.     {
  32.         callback(safe_SW_getBoolPref("extensions.smarterwiki." + pref_name));
  33.     };
  34.     if(window.chrome && window.chrome.extension) // detect chrome
  35.     {
  36.         var get_localStorage = function(key, callback) //only used for Chrome
  37.         {    
  38.             chrome.extension.sendRequest({"msg_type": "get_localStorage", "key": key}, function(response)
  39.             {
  40.                 if(callback)
  41.                 {
  42.                     callback(response.value);
  43.                 }
  44.             });
  45.         };
  46.  
  47.         getBoolPref = function(pref_name, callback)
  48.         {
  49.             get_localStorage("pref." + pref_name, function(str)
  50.             {
  51.                 callback(str == "true");
  52.             });
  53.         };
  54.         
  55.         SW_$ = $;
  56.         SW_LOG = function(){};
  57.         $.get = function(url, data, callback, type)
  58.         {
  59.             chrome.extension.sendRequest({"msg_type": "$.get", "url": url, "data": data, "type": type}, function(response)
  60.             {
  61.                 if(callback)
  62.                 {
  63.                     callback(response.data, response.textStatus);
  64.                 }
  65.             });            
  66.         };
  67.     }    
  68.     
  69.     
  70.     if(!(self === top)) //do not execute in iframe
  71.     {
  72.         return;
  73.     }
  74.     var blacklisted_domains = ["www.met.ie", 
  75.                 "blackle.com", 
  76.                 "www.getresponse.com",
  77.                 "buzz.bazooka.se", 
  78.                 "www.ebay.com", 
  79.                 "forums.macrumors.com",
  80.                 "www.tricentis.com"];
  81.     for(var i = 0; i < blacklisted_domains.length; i++) {
  82.         if(blacklisted_domains[i] == window.location.host) {
  83.             return;
  84.         }
  85.     }
  86.     
  87.     var blacklisted_urls = []; //"http://www.google.com/"];
  88.     for(var i = 0; i < blacklisted_urls.length; i++)
  89.     {
  90.         if(blacklisted_urls[i] == window.location.href) {
  91.             return;
  92.         }
  93.     }
  94.     
  95.     var is_invalid_page = $("a").length > 1500;
  96.     if(!is_invalid_page)
  97.     {
  98.         $("body > *").each(function() {
  99.             if($(this).css("position") == "absolute" && 
  100.                 $(this).css("display") != "none" && 
  101.                 $(this).css("width") != "0px" && 
  102.                 $(this).css("height") != "0px" && 
  103.                 $(this).css("visibility") != "hidden"
  104.             ) // && $(this).css("top") != "" && $(this).attr("id") != "qlauncher-floater"
  105.             {
  106.                 $(this).addClass("broke-endless-pages");
  107.                 is_invalid_page = true;
  108.                 return false;
  109.             }
  110.         });
  111.     }
  112.     if(is_invalid_page) {
  113.         return;
  114.     }
  115.     
  116.     
  117.     
  118.     var page_str = window.page_str || "Page";
  119.     var loading_next_page_str = window.loading_next_page_str || "Loading next page...";
  120.     
  121.     
  122.     
  123.     //rel="next, Next, >>, More, Newer, >, <<, Older, ...
  124.     //page, entry, all
  125.     //Next: <a></a>
  126.     //"Page 1 ╗ Older" - twitter
  127.     //bigger font? lower score if have to share features?
  128.     //ENSURE SAME DOMAIN!!!!!!!!!!
  129.     //
  130.     /*
  131.     var doc = document;
  132.     var xpath = "//a[contains(translate(.,' ', ''), 'next') or contains(translate(following-sibling::node(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ ', ''), 'common')]";
  133.     //"//[REMOVE THIS]*[contains(translate(.,' ', ''),'cat')]";
  134.     <a href="xpath_axes.asp">
  135.     <img width="100" height="20" border="0" alt="Next" src="/images/btn_next.gif"/>
  136.     </a>
  137.     var result = doc.evaluate(xpath, doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); 
  138.     for(var i = 0; i < result.snapshotLength; i++)
  139.     {
  140.         var candidate = result.snapshotItem(i);
  141.         if(candidate.nodeName == "#cdata-section")
  142.         {
  143.             continue;//ignore cdata
  144.         }
  145.         var text = candidate.textContent;
  146.         console.log(text);
  147.     }
  148.     */
  149.     
  150.     var shared_prefix_len = function(str_a, str_b)
  151.     {
  152.         var len = Math.min(str_a.length, str_b.length);
  153.         for(var i = 0; i < len; i++)
  154.         {
  155.             if(str_a.charAt(i) != str_b.charAt(i))
  156.             {
  157.                 return i;
  158.             }
  159.         }
  160.         return len;
  161.     };    
  162.     
  163.     var num_path_diff = function(url1, url2)
  164.     {
  165.         var get_paths = function(url)
  166.         {
  167.             return url.split(new RegExp("([^/?]*)"));
  168.         };
  169.         var paths1 = get_paths(url1);
  170.         var paths2 = get_paths(url2);
  171.         var num_common_paths = 0;
  172.         while(num_common_paths < Math.min(paths1.length, paths2.length) && 
  173.             (paths1[num_common_paths] == paths2[num_common_paths]))
  174.         {
  175.             num_common_paths++;
  176.         }
  177.         return paths1.length + paths2.length - 2 * num_common_paths;
  178.     };
  179.  
  180.     var get_a_matcher = function(keywords)
  181.     {
  182.         keyword += " ";
  183.         var expr1s = [];
  184.         for(var i = 0; i < keywords.length; i++)
  185.         {
  186.             var keyword = keywords[i];
  187.             //var verify_length1 = "string-length(translate(., ' ', '')) <= 20";
  188.             //var verify_length2 = "string-length(translate(., ' ', '')) >= 1";
  189.             var starts_with = "starts-with(concat(., ' '), '" + keyword + "')";
  190.             var contains = "contains(translate(.,' ', ''), '" + keyword + "')";
  191.             var maybe_ends_with = "string-length(substring-after(concat(., ' '), '" + keyword + "')) = 0";
  192.             var keyword_expr = "("/* + verify_length1 + " and " + verify_length2 + " and ("*/ + starts_with + " or (" + contains + " and " + maybe_ends_with + "))"/* + ")"*/;
  193.             expr1s.push(keyword_expr);
  194.         }        
  195.         var expr2s = [];
  196.         var p_sib = "translate(concat(preceding-sibling::node()[2], preceding-sibling::node()[1], preceding-sibling::node()[0]), ' ', '')";
  197.         var f_sib = "translate(concat(following-sibling::node()[0], following-sibling::node()[1], following-sibling::node()[2]), ' ', '')";
  198.         for(var i = 0; i < keywords.length; i++)
  199.         {
  200.             var keyword = keywords[i];
  201.             expr2s.push("(contains(substring(" + p_sib + ", string-length(" + p_sib + ") - 35), '" + keyword + "') or contains(substring(" + f_sib + ", string-length(" + f_sib + ")), '" + keyword + "'))");
  202.         }
  203.         var verify_length1 = "string-length(translate(., ' ', '')) <= 20";
  204.         var verify_length2 = "string-length(translate(., ' ', '')) >= 1";
  205.         var xpath_expr = ".//a[@rel='next' or (" + verify_length1 + " and " + verify_length2 + " and (" + expr1s.join(" or ") + " or " + expr2s.join(" or ") + "))]";
  206.         //alert(xpath_expr);
  207.         return function(contextNode) {
  208.             var result = document.evaluate(xpath_expr, contextNode, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  209.             var nodes = [];
  210.             for(var i = 0; i < result.snapshotLength; i++)
  211.             {
  212.                 nodes.push(result.snapshotItem(i));
  213.             }
  214.             return nodes;
  215.         };
  216.     };
  217.     
  218.     var $a_text_tester = function(keyword)
  219.     {
  220.         keyword += " ";
  221.         var verify_length1 = "string-length(translate(., ' ', '')) <= 20";
  222.         var verify_length2 = "string-length(translate(., ' ', '')) >= 1";
  223.         var starts_with = "starts-with(concat(., ' '), '" + keyword + "')";
  224.         var contains = "contains(concat(., ' '), '" + keyword + "')";
  225.         var maybe_ends_with = "string-length(substring-after(concat(., ' '), '" + keyword + "')) = 0";
  226.         var keyword_expr = "(" + verify_length1 + " and " + verify_length2 + " and (" + starts_with + " or (" + contains + " and " + maybe_ends_with + "))" + ")";
  227.         var xpath_expr = "" + keyword_expr + "";// or ends-with(translate(substring(., 0, 35),' ', ''), '" + keyword + "'))]";
  228.         return function($a){
  229.             var result = document.evaluate(xpath_expr, $a[0], null, XPathResult.BOOLEAN_TYPE, null);
  230.             //not a perfect emulation of ends-with but XPath 1.0 is too FUCKING DUMB.
  231.             return result.booleanValue;
  232.         };
  233.     };
  234.     var $a_parent_text_tester = function(keyword)
  235.     {
  236.         keyword += " ";
  237.         var p_sib = "translate(concat(preceding-sibling::node()[2], preceding-sibling::node()[1], preceding-sibling::node()[0]), ' ', '')";
  238.         var f_sib = "translate(concat(following-sibling::node()[0], following-sibling::node()[1], following-sibling::node()[2]), ' ', '')";
  239.         var xpath_expr = "string-length(translate(., ' ', '')) <= 20 and string-length(translate(., ' ', '')) >= 1 and ((contains(substring(" + p_sib + ", string-length(" + p_sib + ") - 35), '" + keyword + "')) or (contains(substring(" + f_sib + ", string-length(" + f_sib + ")), '" + keyword + "')))";
  240.         //alert(xpath_expr);
  241.         return function($a){
  242.             var result = document.evaluate(xpath_expr, $a[0], null, XPathResult.BOOLEAN_TYPE, null);
  243.             return result.booleanValue;
  244.         };
  245.     };    
  246.     var $a_adjust_weight_on_text = function(weight, feat_len)
  247.     {
  248.         return function($a)
  249.         {
  250.             var text_len = $a.text().length;
  251.             return text_len ? weight * feat_len / text_len : 0;
  252.         };
  253.     };
  254.     var $a_identity = function(val)
  255.     {
  256.         return function($a) {
  257.             return val;
  258.         };
  259.     };
  260.     
  261.     var features = [
  262.         [function($a){
  263.             return $a.attr("rel") == "next";
  264.         }, 
  265.             $a_identity(5000)],//sometimes abused :(
  266.         [$a_text_tester("next"), //   /^.{0,5}next.{0,5}$/),
  267.             $a_adjust_weight_on_text(6000, 4)],
  268.         [$a_text_tester("Next"), //   /^.{0,5}next.{0,5}$/),
  269.             $a_adjust_weight_on_text(5000, 4)],
  270.         [$a_text_tester("\u00bb"),//» //>>|\u00bb
  271.             $a_identity(4000)],
  272.         [$a_text_tester("more"),
  273.             $a_adjust_weight_on_text(800, 4)],
  274.         [$a_text_tester("More"),
  275.             $a_adjust_weight_on_text(1000, 4)],
  276.         [$a_text_tester("newer"),
  277.             $a_adjust_weight_on_text(900, 5)],
  278.         [$a_text_tester("Newer"),
  279.             $a_adjust_weight_on_text(1100, 5)],
  280.         [$a_text_tester(">>"),
  281.             $a_identity(1000)],
  282.         [$a_text_tester(">"),
  283.             $a_identity(600)],
  284.         [$a_text_tester("\u00AB"),
  285.             $a_identity(1500)],
  286.         [$a_text_tester("older"),
  287.             $a_adjust_weight_on_text(600, 5)],
  288.         [$a_text_tester("Older"),
  289.             $a_adjust_weight_on_text(700, 5)],
  290.         [$a_text_tester("Older Posts"),
  291.             $a_adjust_weight_on_text(800, 5)],
  292.         [$a_text_tester("Older posts"),
  293.             $a_adjust_weight_on_text(780, 5)],
  294.         [$a_text_tester("<"),
  295.             $a_identity(350)],
  296.  
  297.  
  298.         [$a_parent_text_tester("next"),
  299.             $a_identity(500)],
  300.         [$a_parent_text_tester("Next"),
  301.             $a_identity(550)],
  302.         [$a_parent_text_tester("\u00bb"),//» //>>|\u00bb
  303.             $a_identity(500)],
  304.         [$a_parent_text_tester("more"),
  305.             $a_identity(300)],
  306.         [$a_parent_text_tester("More"),
  307.             $a_identity(300)],
  308.         [$a_parent_text_tester("newer"),
  309.             $a_identity(300)],
  310.         [$a_parent_text_tester("Newer"),
  311.             $a_identity(300)],
  312.         [$a_parent_text_tester(">>"),
  313.             $a_identity(400)],
  314.         [$a_parent_text_tester(">"),
  315.             $a_identity(100)],
  316.         [$a_parent_text_tester("\u00AB"),
  317.             $a_identity(200)],
  318.         [$a_parent_text_tester("older"),
  319.             $a_identity(100)],
  320.         [$a_parent_text_tester("Older"),
  321.             $a_identity(100)],
  322.         [$a_parent_text_tester("<"),
  323.             $a_identity(100)],
  324.     ];
  325.     var find_matching_as = get_a_matcher(["next", "Next", //"\u00bb", 
  326.                 "more", "More", "newer", "Newer", ">>", ">", "\u00AB",
  327.                 "older", "Older", "<"]);
  328.  
  329.     var check_scroll = function() 
  330.     {
  331.         getBoolPref("enable_endless_pages", function(pref_value)
  332.         {
  333.             if(pref_value)
  334.             {
  335.                 var scrollHeight = document.documentElement.scrollHeight;
  336.                 var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
  337.                 var clientHeight = $(window).height(); //Math.min(document.documentElement.clientHeight, document.body.clientHeight);
  338.                 var remaining = scrollHeight - scrollTop - clientHeight;
  339.                 //alert(remaining);
  340.                 if(remaining < 400)
  341.                 {
  342.                     setTimeout(function()
  343.                     {
  344.                         load_next_page();
  345.                     }, 0);
  346.                 }
  347.             }
  348.         });
  349.     };
  350.     
  351.     $(window).scroll(check_scroll);
  352.     setInterval(check_scroll, 300);
  353.     
  354.     var is_subset_of = function(set1, set2)
  355.     {
  356.         if(set1.length != set2.length) {
  357.             return false;
  358.         }
  359.         for(var i = 0; i < set1.length; i++) {
  360.             if(set1[i] && !set2[i]) {
  361.                 return false;
  362.             }
  363.         }
  364.         return true;
  365.     };
  366.     
  367.     var $last_loaded_page = null;
  368.     var prev_best_has_feature = null;
  369.     var prev_features_count = null;
  370.     var identify_next_link = function()
  371.     {
  372.         /*//addons.mozilla.org is https
  373.         if(/https:/.test(window.location.href)) {
  374.             return null;
  375.         }
  376.         */
  377.         
  378.         var is_valid_url = function(url)
  379.         {
  380.             return url.indexOf(window.location.host) != -1 && 
  381.                     url.indexOf("#") == -1 && 
  382.                     url != window.location.href && 
  383.                     num_path_diff(url, window.location.href) <= 6 && 
  384.                     url.indexOf("random") == -1;
  385.         };
  386.         
  387.         var startTime = new Date().getTime();
  388.         
  389.         var features_count = [];
  390.         for(var i = 0; i < features.length; i++)
  391.         {
  392.             features_count.push(0);
  393.         }
  394.         
  395.         var $links = $(find_matching_as($last_loaded_page ? $last_loaded_page[0] : document));
  396.         $links.each(function(){
  397.             var url = this.toString();
  398.             if(is_valid_url(url))
  399.             {
  400.                 var $a = $(this);
  401.                 var $a_has_feature = [];
  402.                 for(var i = 0; i < features.length; i++)
  403.                 {
  404.                     if(features[i][0]($a))
  405.                     {
  406.                         $a_has_feature.push(true);
  407.                         features_count[i] += 1;
  408.                     }
  409.                     else
  410.                     {
  411.                         $a_has_feature.push(false);
  412.                     }                    
  413.                 }
  414.                 $a.data("has_feature", $a_has_feature);
  415.                 //alert($a[0].toString() + " " + $a_has_feature);
  416.             }
  417.         });
  418.         
  419.         
  420.         var compute_score = function(url, $a, features_count)
  421.         {
  422.             var $a_has_feature = $a.data("has_feature");
  423.             var score = 0;
  424.             for(var i = 0; i < $a_has_feature.length; i++) {
  425.                 if($a_has_feature[i]) {
  426.                     score += features[i][1]($a) / (features_count[i] ? features_count[i] : 1);
  427.                 }
  428.             }
  429.             SW_LOG("before: " + score + " " + url);
  430.             var adjustment = ((1 / num_path_diff(url, window.location.href)) +  
  431.                 (shared_prefix_len(url, window.location.href) / Math.min(url.length, window.location.href.length))) / 2;//favor longer urls over shorter ones
  432.             score = score * adjustment;
  433.             SW_LOG("after: " + score + " " + url);
  434.             $a.addClass("score-" + score);
  435.             return score;
  436.         };
  437.         
  438.         
  439.         var max_score = 0;
  440.         var best_candidate = null;
  441.         $links.each(function(){
  442.             var url = this.toString();
  443.             if(is_valid_url(url))
  444.             {
  445.                 var $a = $(this);
  446.                 var $a_has_feature = $a.data("has_feature");
  447.                 if(prev_best_has_feature)
  448.                 {
  449.                     if(is_subset_of(prev_best_has_feature, $a_has_feature))
  450.                     {
  451.                         var score = compute_score(url, $a, prev_features_count);
  452.                         if(score > max_score)
  453.                         {
  454.                             max_score = score;
  455.                             best_candidate = $a;
  456.                         }
  457.                         SW_LOG("matched previous");
  458.                     }
  459.                 }
  460.                 else
  461.                 {
  462.                     var score = compute_score(url, $a, features_count);
  463.                     if(score > max_score)
  464.                     {
  465.                         max_score = score;
  466.                         best_candidate = $a;
  467.                     }
  468.                 }
  469.             }
  470.         });
  471.  
  472.         var endTime = new Date().getTime();
  473.         if(max_score >= 400)
  474.         {
  475.             SW_LOG("time: " + (endTime - startTime) + " score: " + max_score + ": " + best_candidate + ": " + best_candidate[0].toString() + ": " + best_candidate.text());
  476.         }
  477.         
  478.         if(max_score >= 400)
  479.         {
  480.             //alert(": " + features_count);
  481.             if(!prev_best_has_feature)
  482.             {
  483.                 prev_best_has_feature = best_candidate.data("has_feature");
  484.                 prev_features_count = features_count;
  485.             }
  486.             return best_candidate;
  487.         }
  488.         else
  489.         {
  490.             return null;
  491.         }
  492.     };
  493.     
  494.     var loading_next_page = false;
  495.     var loaded_urls = {};
  496.     //var diditonce = false;
  497.     var load_next_page = function()
  498.     {
  499.         /*
  500.         if(diditonce)
  501.         {
  502.             return;
  503.         }
  504.         else
  505.         {   
  506.             diditonce = true;
  507.         }
  508.         */
  509.         if(loading_next_page)
  510.         {
  511.             return;
  512.         }
  513.         else
  514.         {
  515.             loading_next_page = true;
  516.         }
  517.         
  518.         var $next_link = identify_next_link();
  519.         if($next_link)
  520.         {
  521.             var url = $next_link[0].toString();
  522.             
  523.             if(!(url in loaded_urls))
  524.             {
  525.                 loaded_urls[url] = null;
  526.  
  527.                 $next_link.addClass("endless-pages-found-next-link");
  528.                 SW_LOG(url + ":" + $next_link.text());
  529.  
  530.                 var loading_text = loading_next_page_str;
  531.                 $("body").append($('<div id="endless-pages-loading"><img id="endless-pages-loading-spinner" src="http://static.smarterfox.com/media/smarterwiki/endless_pages/spinner.gif" alt="spinner" />' + loading_text + '</div>').fadeIn());
  532.  
  533.                 var insert_url = function(url)
  534.                 {
  535.                     $.ajax({
  536.                         type: "GET",
  537.                         url: url,
  538.                         success: function(data)
  539.                         {
  540.                             var redirect_url = insert_next_page(url, data);
  541.                             if(redirect_url)
  542.                             {
  543.                                 insert_url(redirect_url);
  544.                             }
  545.                             else
  546.                             {
  547.                                 $("#endless-pages-loading").fadeOut(function() {
  548.                                     $(this).remove();
  549.                                     loading_next_page = false;
  550.                                 });
  551.                             }
  552.                         }, 
  553.                         error: function()
  554.                         {
  555.                             $("#endless-pages-loading").fadeOut(function() {
  556.                                 $(this).remove();
  557.                                 // loading_next_page = false; // don't try again
  558.                             });
  559.                         },
  560.                         dataType: "html",
  561.                         beforeSend: function(req)
  562.                         {
  563.                             req.setRequestHeader("X-moz", "prefetch");
  564.                         }
  565.                     });
  566.                 };
  567.                 insert_url(url);
  568.             }
  569.         }
  570.         //insert_next_page('<html><head></head><body>abcdef<p></body></html>', "text/xml");
  571.     };
  572.     
  573.     
  574.     /*
  575.     var insert_next_page = function(url)
  576.     {
  577.         var $iframe = $('<iframe src="' + url + '" style="height: 0; width: 0; border: none; display: none;"></iframe>').append($("body"));
  578.         $iframe.load(function()
  579.         {
  580.             var next_doc = $iframe[0].contentDocument;
  581.         });
  582.     };//what about frame busting code???
  583.     */
  584.     
  585.     var num_pages_inserted = 0;
  586.     var insert_next_page = function(url, doc_str)//mimetype="text/xml"
  587.     {
  588.         var match = new RegExp("<\\s*body[^<>]*>([\\s\\S]*)<\\s*/\\s*body\\s*>").exec(doc_str);
  589.         if(!match)
  590.         {//some people, like Google, are retarded and are too fucking penny pinching to pay for 7 bytes.
  591.             match = new RegExp("<\\s*body[^<>]*>([\\s\\S]*)$").exec(doc_str);
  592.         }
  593.         if(match)
  594.         {
  595.             var inner_source = match[1];
  596.             if(inner_source)
  597.             {
  598.                 //get rid of scripts
  599.                 inner_source = inner_source.replace(new RegExp("<\\s*script[^<>]*>([\\s\\S]*?)<\\s*/\\s*script\\s*>", ["gi"]), "");
  600.                 inner_source = inner_source.replace(new RegExp("(<\\s*noscript[^<>]*>)|(<\\s*/\\s*noscript\\s*>)", ["gi"]), "");
  601.                 inner_source = inner_source.replace(new RegExp("(<\\s*noscript[^<>]*>)|(<\\s*/\\s*noscript\\s*>)", ["gi"]), "");
  602.  
  603.                 var m = new RegExp('(<\\s*meta[^<>]*HTTP-EQUIV="refresh"[^<>]*content="[^<>]*url=([^<>;]*)(;[^<>]+|)"[^<>]*>)', ["gi"]).exec(inner_source);
  604.                 if(m)
  605.                 {
  606.                     var redirect_url = m[2];
  607.                     return redirect_url;
  608.                 }
  609.                 inner_source = inner_source.replace(new RegExp("(<\\s*meta[^<>]*>)(([\\s\\S]*?)(<\\s*/\\s*meta\\s*>))?", ["gi"]), "");
  610.                 //inner_source = inner_source.replace(new RegExp("<\\s*object[^<>]*>([\\s\\S]*?)<\\s*/\\s*object\\s*>", ["gi"]), "");
  611.                 //inner_source = inner_source.replace(new RegExp("<\\s*embed[^<>]*>([\\s\\S]*?)<\\s*/\\s*embed\\s*>", ["gi"]), "");
  612.                 //<meta HTTP-EQUIV="refresh" content="0;url=http://images.google.com/images?hl=en&client=firefox-a&rls=org.mozilla:en-US:official&um=1&q=a&sa=N&start=63&ndsp=21&gbv=1&ei=8Jd8StPqOIuYsgPboqjvCg">
  613.                 //SW_LOG(inner_source);
  614.  
  615.                 var $loaded_by_endless_pages = $("#loaded-by-endless-pages");
  616.                 if($loaded_by_endless_pages.length == 0)
  617.                 {
  618.                     $loaded_by_endless_pages = $('<div id="loaded-by-endless-pages"></div>')
  619.                                 .css("margin-top", $("body").css("margin-bottom"))
  620.                                 .css("padding-top", $("body").css("padding-bottom"))
  621.                                                     .appendTo("body");
  622.                 }
  623.                 num_pages_inserted += 1;
  624.                 var txt = page_str + " " + (num_pages_inserted + 1) + "";
  625.                 var $page_break_div = $('<div class="endless-pages-page-break"><div class="endless-pages-page-break-desc">- <img class="smarterfox-icon" src="http://static.smarterfox.com/media/smarterwiki/smarterfox-logo.png" /><a class="endless-pages-page-break-link" href="' + url + '">' + txt + '</a> -</div></div>')
  626.                                             .appendTo($loaded_by_endless_pages);   
  627.                                             
  628.                                             
  629.                 var parse_px = function(px_s)
  630.                 {
  631.                     var m = /(\d+)px/.exec(px_s);
  632.                     return (m && parseInt(m[1])) || 0;
  633.                 };
  634.                 var $loaded_page_div = $('<div class="endless-pages-loaded-page"></div>')
  635.                                             .append(inner_source)
  636.                                             .appendTo($loaded_by_endless_pages);
  637.                 $loaded_page_div.css("padding-top", 54 + parse_px($("body").css("margin-top")) + "px");
  638.                     //$loaded_page_div.css("margin-bottom", $("body").css("margin-bottom"));
  639.                     
  640.                 if($last_loaded_page)
  641.                 {
  642.                     $last_loaded_page.css("margin-bottom", $("body").css("margin-bottom"));
  643.                 }
  644.                 $last_loaded_page = $loaded_page_div;
  645.             }
  646.             /*
  647.             var next_doc = new DOMParser().parseFromString(doc_str, mimetype);
  648.             $(next_doc.body, next_doc).each(function()
  649.             {
  650.                 if(this.nodeName != "script")
  651.                 {
  652.                     $next_page_div[0].appendChild(document.adoptNode(this));
  653.                 }
  654.             });
  655.             */
  656.         }
  657.     };
  658. });